package cn.lanqiao.facelogin.service.impl;

import cn.lanqiao.facelogin.BaiDuFace.FaceAdd;
import cn.lanqiao.facelogin.BaiDuFace.FaceSearch;
import cn.lanqiao.facelogin.BaiDuFace.FaceUpdate;
import cn.lanqiao.facelogin.BaiDuFace.JSONDataReturnValue;
import cn.lanqiao.facelogin.domain.*;
import cn.lanqiao.facelogin.mapper.LoginDataMapper;
import cn.lanqiao.facelogin.service.LoginService;
import cn.lanqiao.facelogin.utils.BASE64SaveToLocalImage;
import cn.lanqiao.facelogin.utils.JwtUtil;
import cn.lanqiao.facelogin.utils.SendCodeUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * @author Heroleaves
 */
@Service
public class LoginServiceImpl extends ServiceImpl<LoginDataMapper, LoginData> implements LoginService {

    private static final Pattern HK_PATTERN = Pattern.compile("^(5|6|8|9)\\d{7}$");
    private static final Pattern CHINA_PATTERN = Pattern.compile("^((13[0-9])|(14[0,1,4-9])|(15[0-3,5-9])|(16[2,5,6,7])|(17[0-8])|(18[0-9])|(19[0-3,5-9]))\\d{8}$");
    private static final Pattern NUM_PATTERN = Pattern.compile("[0-9]+");

    @Autowired
    private LoginDataMapper loginDataMapper;

    SendCodeUtils sendCodeUtils = new SendCodeUtils();

    public static boolean isChinaPhoneLegal(String str) throws PatternSyntaxException {
        Matcher m = CHINA_PATTERN.matcher(str);
        return m.matches();
    }

    public static boolean isHKPhoneLegal(String str) throws PatternSyntaxException {

        Matcher m = HK_PATTERN.matcher(str);
        return m.matches();
    }

    public static boolean isPhoneLegal(String str) throws PatternSyntaxException {
        return isChinaPhoneLegal(str) || isHKPhoneLegal(str);
    }

    public static boolean isNumeric(String string) {
        return NUM_PATTERN.matcher(string).matches();
    }

    @Override
    public boolean addFaceId(String faceToken, String timestamp) {
        return loginDataMapper.addFaceId(faceToken, timestamp);
    }

    /**
     * 数据库查找手机号
     *
     * @param tel 手机号
     * @return
     */
    @Override
    public boolean telQuery(String tel) {
        QueryWrapper<LoginData> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("tel", tel);
        List<LoginData> list = list(objectQueryWrapper);
        if (list.size() == 0) {
            return true;
        } else {
            return false;
        }
    }


    @Override
//    保存电话号码到数据库
    public Result saveThePhoneNumber(String tel, String telCode) {
        Jedis jedis = new Jedis("192.168.80.131", 6379);
        String telCodeRedis = jedis.get("CODE_" + tel);
//        比对用户输入的验证码
        if (telCode.equals(telCodeRedis)) {
//            在数据库查询当前手机号，有返回false;没有返回true
            boolean b = telQuery(tel);
            if (b) {
//                获取时间戳
                String timestamp = String.valueOf(System.currentTimeMillis());
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
//                把手机号和时间戳保存到数据库
                save(new LoginData(tel, uuid, null, telCode, null, null));
                Map<String, String> token = new HashMap<>();
                token.put(tel, uuid);
                String tokenNew = JwtUtil.getToken(token);
                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.FACE_UPLOAD_SUCCESS, tokenNew + "&" + uuid);
            } else {
                String uuid = loginDataMapper.selectUUid(tel);
                Map<String, String> token = new HashMap<>();
                token.put(tel, uuid);
                String tokenNew = JwtUtil.getToken(token);
                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.LOGIN_SUCCESS_MSG, tokenNew + "&" + uuid);
            }
        } else {
            return new Result(false, ResParameter.DENY_THIS_REQUEST, ResParameter.LOGIN_CODE_MISTAKE, null);
        }
    }


    @Override
    //发送验证码
    public Result sendTheVerificationCode(String tel) {
        Jedis jedis = new Jedis("192.168.80.131", 6379);
        int i = 0;
        String telCode = sendCodeUtils.getCode();
//        判断手机号格式是否正确
        if (isPhoneLegal(tel)) {
//查询手机号发送次数
            if ((jedis.hget(tel, "count") == null)) {
                jedis.setex("CODE_" + tel, TelCode.PHONE_VERIFICATION_CODE_COUNTDOWN, telCode);
                jedis.hset(tel, "count", TelCode.NUMBER_OF_PHONE_CALLS);
                jedis.expire(tel, TelCode.MOBILE_PHONE_VERIFICATION_CODE_COUNTDOWN);
                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.SEND_CODE_SUCCESS, telCode);
            } else {
                String countTwo = jedis.hget(tel, "count");
                i = Integer.parseInt(countTwo);
                if (i < 3) {
                    jedis.setex("CODE_" + tel, TelCode.PHONE_VERIFICATION_CODE_COUNTDOWN, telCode);
//                    jedis.expire("CODE_" + tel, TelCode.PHONE_VERIFICATION_CODE_COUNTDOWN);
                    jedis.hset(tel, "count", String.valueOf(++i));
                    jedis.expire(tel, TelCode.MOBILE_PHONE_VERIFICATION_CODE_COUNTDOWN);
                    return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.SEND_CODE_SUCCESS, telCode);
                } else {
                    return new Result(false, ResParameter.DENY_THIS_REQUEST, ResParameter.SEND_CODE_COUNT_ZERO, null);
                }
            }
        }
        return new Result(false, null, null, null);
    }

    @Override
    public Result faceDataUpdate(String base64, LoginData loginData) throws Exception {
//        String jsonFaceSearch = FaceSearch.m1(base64);
//        JsonResult jsonResult = JSONDataReturnValue.m1(jsonFaceSearch);
////        查询人脸数据库有没有当前人脸，没有为false
//        if (!jsonResult.isResult()) {
////把当前所接收的人脸保存到baidu人脸数据库
//            String jsonFaceAdd = FaceAdd.m1(base64, loginData);
//            Result loginDataTwo = JSONDataReturnValue.m2(jsonFaceAdd, loginData);
//            if (loginDataTwo.isStatus()) {
//                Object faceToken = loginDataTwo.getJson();
//                System.out.println(faceToken);
//                UpdateWrapper<LoginData> updateWrapper = new UpdateWrapper<>();
//                updateWrapper.eq("tel", loginData.getTel());
//                updateWrapper.set("face_token", faceToken);
//                int update = loginDataMapper.update(null, updateWrapper);
//                if (update == 1) {
//                    BASE64SaveToLocalImage.m1(base64, faceToken);
//                }
//                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.FACE_UPDATED_SUCCESSFULLY, null);
//            } else {
//                return new Result(false, ResParameter.DENY_THIS_REQUEST, ResParameter.FACE_DETECT_FAIL, null);
//            }
//        } else if (jsonResult.isResult() && jsonResult.getJson() != loginData.getTel()) {
//            String jsonFaceAdd = FaceAdd.m1(base64, loginData);
//            Result loginDataTwo = JSONDataReturnValue.m2(jsonFaceAdd, loginData);
//            if (loginDataTwo.isStatus()) {
//                Object faceToken = loginDataTwo.getJson();
//                System.out.println(faceToken);
//                UpdateWrapper<LoginData> updateWrapper = new UpdateWrapper<>();
//                updateWrapper.eq("tel", loginData.getTel());
//                updateWrapper.set("face_token", faceToken);
//                int update = loginDataMapper.update(null, updateWrapper);
//                if (update == 1) {
//                    BASE64SaveToLocalImage.m1(base64, faceToken);
//                }
//            } else {
//                return new Result(false, ResParameter.DENY_THIS_REQUEST, ResParameter.FACE_DETECT_FAIL, null);
//            }
//        } else {
//            String jsonFaceUpdate = FaceUpdate.m1(base64, loginData);
//            String faceTokenOld = loginDataMapper.selectFaceToken(loginData.getTel());
//            File file = new File("src/main/resources/static/img/" + faceTokenOld + ".png");
//            file.delete();
//            Result result = JSONDataReturnValue.m2(jsonFaceUpdate, loginData);
//            Object faceToken = result.getJson();
//            UpdateWrapper<LoginData> updateWrapper = new UpdateWrapper<>();
//            updateWrapper.eq("tel", loginData.getTel());
//            updateWrapper.set("face_token", faceToken);
//            int update = loginDataMapper.update(null, updateWrapper);
//            if (update == 1) {
//                BASE64SaveToLocalImage.m1(base64, faceToken);
//                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.FACE_UPDATED_SUCCESSFULLY, null);
//            }
//        }
        return null;
    }

    /**
     * 人脸数据更新
     *
     * @param base64
     * @param tel
     * @return
     * @throws Exception
     */
    @Override
    public Result faceUpdate(String base64, String tel) throws Exception {
        JsonResult jsonResult = JSONDataReturnValue.m1(FaceSearch.m1(base64));
        if (!jsonResult.isResult()) {
            Result result = JSONDataReturnValue.m2(FaceAdd.m1(base64, tel));
            if (result.isStatus()) {
                Object faceToken = result.getData();
                UpdateWrapper<LoginData> UpdateWrapper = new UpdateWrapper<>();
                UpdateWrapper.eq("tel", tel);
                UpdateWrapper.set("face_token", faceToken);
                int update = loginDataMapper.update(null, UpdateWrapper);
                if (update == 1) {
                    BASE64SaveToLocalImage.m1(base64, faceToken);
                }
                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.FACE_ADDED_SUCCESSFULLY, null);
            } else {
                return new Result(false, ResParameter.DENY_THIS_REQUEST, ResParameter.FACE_DETECT_FAIL, null);
            }
        } else if (jsonResult.isResult() && (jsonResult.getJson().equals(tel))) {
            Result faceToken = JSONDataReturnValue.m2(FaceUpdate.m1(base64, tel));
            Object json = faceToken.getData();
            String faceTokenOld = loginDataMapper.selectFaceToken(tel);
            File file = new File("src/main/resources/static/img/" + faceTokenOld + ".png");
            file.delete();
            UpdateWrapper<LoginData> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("tel", tel);
            updateWrapper.set("face_token", json);
            int update = loginDataMapper.update(null, updateWrapper);
            if (update == 1) {
                BASE64SaveToLocalImage.m1(base64, json);
                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.FACE_UPDATED_SUCCESSFULLY, null);
            }
        } else {
            Result result = JSONDataReturnValue.m2(FaceAdd.m1(base64, tel));
            if (result.isStatus()) {
                Object faceToken = result.getData();
                UpdateWrapper<LoginData> UpdateWrapper = new UpdateWrapper<>();
                UpdateWrapper.eq("tel", tel);
                UpdateWrapper.set("face_token", faceToken);
                int update = loginDataMapper.update(null, UpdateWrapper);
                if (update == 1) {
                    BASE64SaveToLocalImage.m1(base64, faceToken);
                }
                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.FACE_ADDED_SUCCESSFULLY, null);
            } else {
                return new Result(false, ResParameter.DENY_THIS_REQUEST, ResParameter.FACE_DETECT_FAIL, null);
            }
        }
        return null;
    }

    /**
     * 通过uuid查询当前人脸faceToken
     *
     * @param uuid uuid
     * @return faceToken
     */
    @Override
    public Result queryFaceToken(String uuid) {
        //通过uuid查询faceToken
        List<LoginData> loginData = loginDataMapper.selectAll(uuid);
        return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, null, loginData);
    }

    @Override
    public Result facelogin(JsonResult jsonResult) {
        String faceId = jsonResult.getJson();
        if (jsonResult.isResult()) {
            QueryWrapper<LoginData> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("face_id", faceId);
            String faceIdTwo = loginDataMapper.selectPhone(faceId);
            System.out.println(faceIdTwo);
        }
        return null;
    }

    /**
     * @param tokenId tokenId
     * @return null
     */
    @Override
    public Result findTokenId(String tokenId) {
        String tokenIdNew = loginDataMapper.findTokenId(tokenId);
        return new Result(true, null, null, tokenIdNew);
    }

    @Override
    public String findTokenIdTel(String tokenId) {
        return loginDataMapper.findTokenIdTel(tokenId);
    }

    /**
     * @param tokenId tokenId
     * @param uName   名称
     * @return
     */
    @Override
    public Result addTokenId(String tokenId, String uName) {
//        String s = loginDataMapper.addToken(tokenId, uName);
        save(new LoginData(null, null, null, null, tokenId, uName));
        System.out.println();
        return null;
    }

    @Override
    public Result giteeSave(String tel, String telCode, String uName, String tokenId) {
        Jedis jedis = new Jedis("192.168.80.131", 6379);
        String telCodeRedis = jedis.get("CODE_" + tel);
//        比对用户输入的验证码
        if (telCode.equals(telCodeRedis)) {
//            在数据库查询当前手机号，有返回false;没有返回true
            boolean b = telQuery(tel);
            if (b) {
//                uuid
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                Map<String, String> token = new HashMap<>();
                token.put(tel, uuid);
                String tokenNew = JwtUtil.getToken(token);
//                把手机号和时间戳保存到数据库
                save(new LoginData(tel, uuid, null, telCode, tokenId, uName));
                return new Result(true, ResParameter.LOGIN_SUCCESS_CODE, ResParameter.FACE_UPLOAD_SUCCESS, tokenNew+"&"+uuid);
            } else {
                return new Result(false, ResParameter.DENY_THIS_REQUEST, ResParameter.THE_CURRENT_PHONE_NUMBER_HAS_BEEN_REGISTERED, null);
            }
        } else {
            return new Result(false, ResParameter.DENY_THIS_REQUEST, ResParameter.LOGIN_CODE_MISTAKE, null);
        }

    }
}
